package models
/*********************************************************/
/********************本文档为数据库结构文档******************/
/***********TimerEvent,LastTimerEvent的数据结构************/
/*********************version:1.0*************************/
/****Copyright (c) 2014年 许剑华. All rights reserved******/
/*********************************************************/
import (
	"github.com/astaxie/beego/orm"
	"time"
	."smart_home/lib"
	"github.com/astaxie/beego"
	//"fmt"

	//m "smart_home/controllers/dataType"
	//"github.com/astaxie/beego/validation"
)
type TimerEvent struct {
	Id          	int64			`orm:"unique;auto"`
	Mac    			string
	EventTime		int
	DeviceType		int
	TimeScale		int
	IRFRQ			int
	OpType			string
	Model			int
	RespCode		int
	Mask			int
	Count			int64
}
type LastTimerEvent struct {
	Id          	int64	`orm:"unique;auto"`
	Mac    			string
	ProductName		string
	DeviceType		string
	User    		*User   `orm:"rel(fk)"` // OneToOne relation

}


//用于控制每个设备是否开启自动控制
type IsOpenMashineLearn struct {
	Id          	int64			`orm:"unique;auto"`
	Open			bool
	Mac				string
	Time            time.Time		`orm:"type(datetime);auto_now_add" `
}

//用于控制系统是否开启自动控制
type SysMashineLearn struct {
	Id          	int64			`orm:"unique;auto"`
	Open			bool
	Time            time.Time		`orm:"type(datetime);auto_now_add" `
}

//
type ParticleSize struct {
	Id          	int64			`orm:"unique;auto"`
	Particlesize	int				`orm:"default(1)"`
	Time            time.Time		`orm:"type(datetime);auto_now_add" `
}

//用于存储
type ThresholdValue struct {
	Id          	int64			`orm:"unique;auto"`
	Threshold		int64					`orm:"default(1)"`
	Time            time.Time		`orm:"type(datetime);auto_now_add" `
}
//用于注册数据表
func init() {
	// 需要在init中注册定义的model
	orm.RegisterModel(new(TimerEvent),new(LastTimerEvent),new(IsOpenMashineLearn),new(ParticleSize),new(ThresholdValue),new(SysMashineLearn))
}
//设置自动控制的阀值
//@param 	 size    	 int64       设置自动控制的阀值
//@return   	         error       返回的错误
func SetThresholdValue(size int64)(error){
	thresholdValue := ThresholdValue{Id: 1}
	o := orm.NewOrm()
	err := o.Read(&thresholdValue, "Id")
	if err == orm.ErrNoRows {
		thresholdValue.Threshold = size
		_, err = o.Insert(&thresholdValue)
		if err != nil{
			return err
		}
	} else if err == orm.ErrMissPK {
		thresholdValue.Threshold = size
		_, err = o.Insert(&thresholdValue)
		if err != nil{
			return err
		}
	}

	thresholdValue.Threshold = size
	o.Update(&thresholdValue)
	return err
}
//获取自动控制的阀值
//@return 	 size    	 int64       设置自动控制的阀值
//@return    err	     error       返回的错误
func GetThresholdValue()(size int64,err error){
	thresholdValue := ThresholdValue{Id: 1}
	o := orm.NewOrm()
	err = o.Read(&thresholdValue, "Id")
	if err == orm.ErrNoRows {

		thresholdValue.Threshold = DEFAULT_THRESHOLD_SIZE
		_, err = o.Insert(&thresholdValue)
		if err != nil{
			beego.Error("GetThresholdValue err",err)

			return 0,err
		}
	} else if err == orm.ErrMissPK {
		thresholdValue.Threshold = DEFAULT_THRESHOLD_SIZE
		_, err = o.Insert(&thresholdValue)
		if err != nil{
			beego.Error("GetThresholdValue err",err)
			return 0,err
		}
	}else if err != nil{
		return 0,err
	}
	//	size = particleSize.Particlesize
	return thresholdValue.Threshold,err
}
//获取自动控制的阀值
//@param 	 size    	 int64       设置自动控制的阀值
//@return    err	     error       返回的错误
func SetParticleSize(size int)(error){
	particleSize := ParticleSize{Id: 1}
	o := orm.NewOrm()
	err := o.Read(&particleSize, "Id")
	if err == orm.ErrNoRows {
		particleSize.Particlesize = size
		_, err = o.Insert(&particleSize)
		if err != nil{
			return err
		}
	} else if err == orm.ErrMissPK {
		particleSize.Particlesize = size
		_, err = o.Insert(&particleSize)
		if err != nil{
			return err
		}
	}

	particleSize.Particlesize = size
	o.Update(&particleSize)
	return err
}
//设置自动控制的最小粒度
//@param 	 size    	 int64       设置自动控制的最小粒度的值
//@return    err	     error       返回的错误
func GetParticleSize()(size int,err error){
	particleSize := ParticleSize{Id: 1}
	o := orm.NewOrm()
	err = o.Read(&particleSize, "Id")
	if err == orm.ErrNoRows {
		beego.Error("GetParticleSize err",err)

		particleSize.Particlesize = DEFAULT_PARTICLE_SIZE
		_, err = o.Insert(&particleSize)
		if err != nil{
			beego.Error("GetParticleSize err",err)
			return 0,err
		}
	} else if err == orm.ErrMissPK {
		particleSize.Particlesize = DEFAULT_PARTICLE_SIZE
		_, err = o.Insert(&particleSize)
		if err != nil{
			beego.Error("GetParticleSize err",err)
			return 0,err
		}
	}else if err != nil{
		return 0,err
	}
//	size = particleSize.Particlesize
	return particleSize.Particlesize,err
}

//设置单个设备是否开启机器学习
//@param 	 mac    	 string       要设置的设备的地址
//@param 	 flag    	 bool          否开启自动控制
//@return    err	     error       返回的错误
func SetMashineLearn(mac string,flag bool)(error){
	openflag := IsOpenMashineLearn{Mac: mac}
	o := orm.NewOrm()

	err := o.Read(&openflag, "mac")
	//fmt.Println("openflag：",openflag)
	if err == orm.ErrNoRows {
		openflag.Open = flag
		_, err = o.Insert(&openflag)
		if err != nil{
			return err
		}
	} else if err == orm.ErrMissPK {
		openflag.Open = flag
		_, err = o.Insert(&openflag)
		if err != nil{
			return err
		}
	}
	openflag.Open = flag
	o.Update(&openflag)
	//fmt.Println("找到数据：",openflag)
	return err
}
//获取设置单个设备是否开启机器学习的标志位
//@param 	 mac    	 string       要设置的设备的地址
//@param 	     	     bool          否开启自动控制
//@return    	         error       返回的错误
func GetMashineLearn(mac string)(bool,error){
	openflag := IsOpenMashineLearn{Mac: mac}
	o := orm.NewOrm()
	err := o.Read(&openflag, "mac")
	if err == orm.ErrNoRows {
		openflag.Open = DEFAULT_MASHINE_LEARN
		_, err = o.Insert(&openflag)
		if err != nil{
			return false,err
		}
	} else if err == orm.ErrMissPK {
		openflag.Open = DEFAULT_MASHINE_LEARN
		_, err = o.Insert(&openflag)
		if err != nil{
			return false,err
		}
	}
	return openflag.Open,err
}
//设置系统是否开启机器学习的标志位
//@param 	 flag    	 bool        设置是否开启系统学习的标志
//@return    	         error       返回的错误
func SetSysMashineLearn(flag bool)(error){
	openflag := SysMashineLearn{Id:1}
	o := orm.NewOrm()

	err := o.Read(&openflag, "Id")
	//fmt.Println("openflag：",openflag)
	if err == orm.ErrNoRows {
		openflag.Open = flag
		_, err = o.Insert(&openflag)
		if err != nil{
			return err
		}
	} else if err == orm.ErrMissPK {
		openflag.Open = flag
		_, err = o.Insert(&openflag)
		if err != nil{
			return err
		}
	}
	openflag.Open = flag
	o.Update(&openflag)
	//fmt.Println("找到数据：",openflag)
	return err
}
//获取设置系统是否开启机器学习的标志位
//@param 	     	     bool          否开启自动控制
//@return    	         error       返回的错误
func GetSysMashineLearn()(bool,error){
	openflag := SysMashineLearn{Id:1}
	o := orm.NewOrm()
	err := o.Read(&openflag, "Id")
	if err == orm.ErrNoRows {
		openflag.Open = DEFAULT_MASHINE_LEARN
		_, err = o.Insert(&openflag)
		if err != nil{
			return false,err
		}
	} else if err == orm.ErrMissPK {
		openflag.Open = DEFAULT_MASHINE_LEARN
		_, err = o.Insert(&openflag)
		if err != nil{
			return false,err
		}
	}
	return openflag.Open,err
}

//func AddEvent (data *DeviceConLog,user *User)(int,error){
//	//	if err := checkUser(u); err != nil {
//	//		return 0, err
//	//	}
//	o := orm.NewOrm()
//	data.User = user
//	id, err := o.Insert(data)
//	return id, err
//}

//获取设备控制的事件
//@param 	 mac    	 string       要设置的设备的地址
//@param 	 devices     []orm.Params          返回的数组
//@return    count	         int64       返回的数组的数量
func GetEvent ()(devices []orm.Params,count int64){
	o := orm.NewOrm()
	device := new(DeviceConLog)
	qs := o.QueryTable(device)
	qs.Values(&devices)
	count, _ = qs.Count()
	return devices, count
}
//添加设备控制的事件
//@param 	 mac    	 string       要设置的设备的地址
//@param 	 devices     []orm.Params          返回的数组
//@return    count	         int64       返回的数组的数量
func AddTimerEvent(data *TimerEvent)(err error){
	o := orm.NewOrm()
	data.Count = 1
	_, err = o.Insert(data)
	return err
}
//设置设备控制的事件
//@param 	 data     	 		TimerEvent          定时事件
//@param 	 event_time     	int                 事件的时间
//@return    para	            []orm.Params        返回的数据的数组
func SetTimerEvent(data TimerEvent,event_time int)(para []orm.Params){
	o := orm.NewOrm()
	time_event := new(TimerEvent)
	qs := o.QueryTable(time_event)

	tt := qs.Filter("Mac",data.Mac).Filter("EventTime",event_time).Filter("OpType",data.OpType)

	tt.Values(&para)
	if para == nil{

		err := AddTimerEvent(&data)
		if err != nil{
			beego.Error("SetTimerEvent err",err)		}
	}else{
		tt.One(time_event)
		time_event.Count++
		_, _ = o.Update(time_event)
	}
	return para
}

//获取所有大于阀值的设备控制的事件
//@param 	 time     			int                 事件的时间
//@return    		            []TimerEvent        返回的数据的数组
//@return        	            int64        返回的数据的数量
//@return     	                error        返回的数据的错误


func GetCountBigToThreshold(time int)([]TimerEvent,int64,error){
	o := orm.NewOrm()
	var time_event []TimerEvent
	//qs := o.QueryTable(time_event)

	//tt := qs.Filter("EventTime",time).
	size ,_ :=GetThresholdValue()
	num,err := o.Raw("SELECT * FROM timer_event WHERE count >= ? and event_time = ?", size,time).QueryRows(&time_event)
	//fmt.Println("num",num,"err",err)
	//fmt.Println("time_event",time_event)

	return time_event,num,err
}


